/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.modules.admin.dto.platform.ApplicationElevatorDetailSearchDTO;
import org.springblade.modules.admin.dto.platform.ElevatorCheckDTO;
import org.springblade.modules.admin.entity.EstateApplicationElevator;
import org.springblade.modules.admin.entity.EstateApplicationForm;
import org.springblade.modules.admin.entity.EstateBuilding;
import org.springblade.modules.admin.entity.EstateElevator;
import org.springblade.modules.admin.enums.ApplicationStatusEnum;
import org.springblade.modules.admin.enums.ApproveStatusEnum;
import org.springblade.modules.admin.enums.EffectiveStatusEnum;
import org.springblade.modules.admin.mapper.EstateApplicationElevatorMapper;
import org.springblade.modules.admin.service.IEstateApplicationElevatorService;
import org.springblade.modules.admin.service.IEstateApplicationFormService;
import org.springblade.modules.admin.service.IEstateBuildingService;
import org.springblade.modules.admin.service.IEstateElevatorService;
import org.springblade.modules.admin.vo.EstateApplicationElevatorVO;
import org.springblade.modules.admin.vo.platform.ApplicationElevatorDetailVo;
import org.springblade.modules.admin.vo.platform.ApplicationElevatorStatusDetailVo;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 物业项目关联申请记录电梯表 服务实现类
 *
 * @author ysq
 * @since 2022-05-27
 */
@Service
public class EstateApplicationElevatorServiceImpl extends BaseServiceImpl<EstateApplicationElevatorMapper, EstateApplicationElevator> implements IEstateApplicationElevatorService {

	/**
	 * 审核状态 1-待审核, 2-通过, 3-不通过
	 */
	private final int[] statuss = {0, 1, 2, 3};

	@Autowired
	private IEstateElevatorService estateElevatorService;

	@Autowired
	private IEstateBuildingService estateBuildingService;

	@Autowired
	@Lazy
	private IEstateApplicationFormService estateApplicationFormService;

	@Autowired
	private IUserService userService;

	@Override
	public IPage<EstateApplicationElevatorVO> selectEstateApplicationElevatorPage(IPage<EstateApplicationElevatorVO> page, EstateApplicationElevatorVO estateApplicationElevator) {
		return page.setRecords(baseMapper.selectEstateApplicationElevatorPage(page, estateApplicationElevator));
	}

	@Override
	public List<Long> getSelectedElevator() {
		List<EstateApplicationElevator> list = this.list(Wrappers.<EstateApplicationElevator>lambdaQuery().in(EstateApplicationElevator::getStatus, ApproveStatusEnum.PENDING.getId(), ApproveStatusEnum.PASSED.getId()));
		List<Long> elevatorIds = list.stream().map(t -> t.getElevatorId()).distinct().collect(Collectors.toList());
		return elevatorIds;
	}

	@Override
	public IPage<ApplicationElevatorDetailVo> list(ApplicationElevatorDetailSearchDTO applicationElevatorDetailSearchDTO) {
		Query query = new Query();
		query.setSize(applicationElevatorDetailSearchDTO.getSize());
		query.setCurrent(applicationElevatorDetailSearchDTO.getCurrent());
		//如果审核人和审核时间筛选表示已经审核过，查询状态审核过的状态
		if (StrUtil.isNotEmpty(applicationElevatorDetailSearchDTO.getUpdateUserName()) || applicationElevatorDetailSearchDTO.getUpdateEndTime() != null) {
			List<Integer> status = new ArrayList<>(3);
			status.add(statuss[2]);
			status.add(statuss[3]);
			applicationElevatorDetailSearchDTO.setStatus(status);
		}
		IPage<ApplicationElevatorDetailVo> page = Condition.getPage(query);
		List<ApplicationElevatorDetailVo> list = baseMapper.list(page, applicationElevatorDetailSearchDTO);
		page.setRecords(list);
		return page;
	}


	@Override
	public IPage<ApplicationElevatorDetailVo> listV2(ApplicationElevatorDetailSearchDTO applicationElevatorDetailSearchDTO) {
		Query query = new Query();
		query.setSize(applicationElevatorDetailSearchDTO.getSize());
		query.setCurrent(applicationElevatorDetailSearchDTO.getCurrent());
		//如果审核人和审核时间筛选表示已经审核过，查询状态审核过的状态
		if (StrUtil.isNotEmpty(applicationElevatorDetailSearchDTO.getUpdateUserName()) || applicationElevatorDetailSearchDTO.getUpdateEndTime() != null) {
			List<Integer> status = new ArrayList<>(3);
			status.add(statuss[2]);
			status.add(statuss[3]);
			applicationElevatorDetailSearchDTO.setStatus(status);
		}
		IPage<ApplicationElevatorDetailVo> page = Condition.getPage(query);
		List<ApplicationElevatorDetailVo> list = baseMapper.listV2(page, applicationElevatorDetailSearchDTO);
		page.setRecords(list);
		return page;
	}

	@Override
	public ApplicationElevatorStatusDetailVo getApplicationElevatorStatusDetail(Long formId) {
		return baseMapper.getApplicationElevatorStatusDetail(formId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean update(ElevatorCheckDTO elevatorCheckDTO) {
		Date date = new Date();
		List<EstateApplicationElevator> estateApplicationElevators = this.listByIds(elevatorCheckDTO.getIds());
		if (estateApplicationElevators == null || estateApplicationElevators.size() == 0) {
			throw new ServiceException("未找到申请的电梯记录请检查ids参数");
		}
		EstateApplicationForm applicationForm = estateApplicationFormService.getById(estateApplicationElevators.get(0).getFormId());
		//状态审核操作
		for (EstateApplicationElevator estateApplicationElevator : estateApplicationElevators) {
			if (elevatorCheckDTO.getStatus() != null) {
				estateApplicationElevator.setStatus(elevatorCheckDTO.getStatus());
				if (elevatorCheckDTO.getStatus() == statuss[2]) {
					EstateBuilding estateBuilding = estateBuildingService.getOne(Wrappers.<EstateBuilding>lambdaQuery().eq(EstateBuilding::getBuildingId, estateApplicationElevator.getBuildingId()).eq(EstateBuilding::getTenantId, estateApplicationElevator.getTenantId()));
					if (estateBuilding == null) {
						estateBuilding = new EstateBuilding();
						estateBuilding.setBuildingId(estateApplicationElevator.getBuildingId());
						estateBuilding.setTenantId(estateApplicationElevator.getTenantId());
						estateBuildingService.save(estateBuilding);
					}
					if (estateBuilding.getDeptId() == null) {
						estateBuilding.setDeptId(estateApplicationElevator.getDeptId());
						estateBuildingService.updateById(estateBuilding);
					}
					EstateElevator estateElevator = estateElevatorService.getOne(Wrappers.<EstateElevator>lambdaQuery().eq(EstateElevator::getElevatorId, estateApplicationElevator.getElevatorId()).eq(EstateElevator::getTenantId, estateApplicationElevator.getTenantId()));
					if (estateElevator != null) {
						//continue;
					} else {
						estateElevator = new EstateElevator();
						estateElevator.setElevatorId(estateApplicationElevator.getElevatorId());
						estateElevator.setEstateBuildingId(estateBuilding.getId());
						estateElevator.setTenantId(estateApplicationElevator.getTenantId());
						estateElevatorService.save(estateElevator);
					}
				}
				this.updateById(estateApplicationElevator);
			}
			if (elevatorCheckDTO.getMaintainIsOpen() != null) {
				List<Long> elevatorIds = estateApplicationElevators.stream().map(EstateApplicationElevator::getElevatorId).collect(Collectors.toList());
				List<EstateElevator> elevatorList = estateElevatorService.list(Wrappers.<EstateElevator>lambdaQuery().in(EstateElevator::getElevatorId, elevatorIds).eq(EstateElevator::getTenantId, estateApplicationElevator.getTenantId()));
				if (elevatorCheckDTO.getMaintainIsOpen()) {
					elevatorList.forEach(o -> {
						o.setMaintainStartTime(elevatorCheckDTO.getMaintainStartTime());
						o.setMaintainEndTime(elevatorCheckDTO.getMaintainEndTime());
						o.setMaintainOperatorId(AuthUtil.getUserId());
						o.setMaintainOperatorName(userService.getById(AuthUtil.getUserId()).getRealName());
						o.setMaintainOperateTime(date);
						if (date.getTime() > elevatorCheckDTO.getMaintainStartTime().getTime() && date.getTime() < elevatorCheckDTO.getMaintainEndTime().getTime()) {
							o.setMaintainStatus(EffectiveStatusEnum.EFFECTED.getStatus());
						}else{
							o.setMaintainStatus(EffectiveStatusEnum.WAIT_EFFECT.getStatus());
						}
					});
				} else if (!elevatorCheckDTO.getMaintainIsOpen()) {
					elevatorList.forEach(o -> {
						o.setMaintainStartTime(null);
						o.setMaintainEndTime(null);
						o.setMaintainOperatorId(null);
						o.setMaintainOperatorName(null);
						o.setMaintainOperateTime(null);
						o.setMaintainStatus(EffectiveStatusEnum.NO_OPEN.getStatus());
					});
				}
				estateElevatorService.updateBatchById(elevatorList);
			}
			if (elevatorCheckDTO.getTlwIsOpen() != null) {
				List<Long> elevatorIds = estateApplicationElevators.stream().map(EstateApplicationElevator::getElevatorId).collect(Collectors.toList());
				List<EstateElevator> elevatorList = estateElevatorService.list(Wrappers.<EstateElevator>lambdaQuery().in(EstateElevator::getElevatorId, elevatorIds).eq(EstateElevator::getTenantId, estateApplicationElevator.getTenantId()));
				if (elevatorCheckDTO.getTlwIsOpen()) {
					elevatorList.forEach(o -> {
						o.setTlwStartTime(elevatorCheckDTO.getTlwStartTime());
						o.setTlwEndTime(elevatorCheckDTO.getTlwEndTime());
						o.setTlwOperatorId(AuthUtil.getUserId());
						o.setTlwOperatorName(userService.getById(AuthUtil.getUserId()).getRealName());
						o.setTlwOperateTime(date);
						if (date.getTime() > elevatorCheckDTO.getTlwStartTime().getTime() && date.getTime() < elevatorCheckDTO.getTlwEndTime().getTime()) {
							o.setTlwStatus(EffectiveStatusEnum.EFFECTED.getStatus());
						}else{
							o.setTlwStatus(EffectiveStatusEnum.WAIT_EFFECT.getStatus());
						}
					});
				} else if (!elevatorCheckDTO.getTlwIsOpen()) {
					elevatorList.forEach(o -> {
						o.setTlwStartTime(null);
						o.setTlwEndTime(null);
						o.setTlwOperatorId(null);
						o.setTlwOperatorName(null);
						o.setTlwOperateTime(null);
						o.setTlwStatus(EffectiveStatusEnum.NO_OPEN.getStatus());
					});
				}
				estateElevatorService.updateBatchById(elevatorList);
			}


			if (elevatorCheckDTO.getStatus() != null) {
				List<EstateApplicationElevator> applicationElevatorList = this.list(Wrappers.<EstateApplicationElevator>lambdaQuery().eq(EstateApplicationElevator::getFormId, estateApplicationElevators.get(0).getFormId()));
				List<EstateApplicationElevator> elevatorList1 = applicationElevatorList.stream().filter(o -> o.getStatus() == statuss[1]).collect(Collectors.toList());
				if (elevatorList1.size() > 0) {
					applicationForm.setStatus(ApplicationStatusEnum.HANDLING.getStatus());
				} else {
					applicationForm.setStatus(ApplicationStatusEnum.HANDLED.getStatus());
				}
				estateApplicationFormService.updateById(applicationForm);
			}
		}
		return true;
	}
}
